package com.kotlin

// 使用关键字 fun 来申明一个函数
// 函数中的参数必须要显示指定 参数类型

// 1、定义带返回值的函数
fun sumWithReturnValue(num1 : Int, num2 : Int) : Int {
    return num1 + num2;
}

// 2、将表达式作为函数体、返回值类型自动推断的函数：
fun sum2(num1: Int, num2: Int) = num1 + num2

// 3、函数返回无意义的值 , 当返回值是 Unit 时，可以省略Unit不写 ==> fun sum3(num1 : Int, num2 : Int) { ... }
fun sum3(num1: Int, num2: Int) : Unit{
    println("sum of $num1 + $num2 = ${num1 + num2}")
}

// 4、函数的参数中带 默认值
fun sumWithDefaultValue(num1: Int = 10,num2: Int = 20) : Int{
    return num1 + num2
}

// 5、方法的覆盖 覆盖方法总是使用与基类型方法相同的默认参数值。 当覆盖一个带有默认参数值的方法时，必须从签名中省略默认参数值
open class A {
    open fun foo(i : Int = 10){
        println("i的值是[$i]")
    }
}
class B : A(){
    // 此时这个覆盖的方法上不可写默认值
    override fun foo(i: Int) {
        println("override i的值是[$i]")
    }
}

// 6、方法参数中带入 lambda 表达式  filter参数为接收一个lambda表达式，在方法的实现中可以看到，接收一个Int类型的参数，返回Boolean值
fun methodParamWithLambda(num1: Int,filter: (Int) -> Boolean) : Boolean{
    var result = filter(num1)
    return result
}

// 7、使用 * 操作符将可变参数以命名参数形式传入
fun varargSum(vararg nums : Int) : Int{
    return nums.sum()
}

// 8、局部函数 -- 类似 js 中的闭包
fun partFunction(nums : IntArray) : Boolean{
    fun find(findValue : Int) : Boolean{
        return nums.any { num -> num == findValue }
    }
    return find(5)
}

// 9、成员函数 - 成员函数调用 Member.memberFunction()
class Member{
    fun memberFunction(){
        println("这个是成员函数")
    }
}


// 主函数
fun main(args: Array<String>) {
    println(sumWithReturnValue(1, 2))
    println(sum2(2, 3))
    sum3(3,4)
    // num1使用传递进入的值,num2使用默认值     （命名参数）
    println(sumWithDefaultValue(num1 = 30))
    B().foo()
    B().foo(20)
    println(methodParamWithLambda(10) { num -> num > 10 })
    println(varargSum(nums = *intArrayOf(10,20,30,40,50)))
    println(partFunction(intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
    Member().memberFunction()
}